#include <stdio.h>
#include "datatypes.h"
#include "globals.h"

void print_atomic_concept(AtomicConcept* ac);
void print_exists(Exists* exists);
void print_conjunction(Conjunction* conjunction);

void print_atomic_role(AtomicRole* ar);

void print_concept(Concept* c) {
	switch (c->type) {
		case ATOMIC_CONCEPT:
			// printf("%d", c->description.concept_id);
			print_atomic_concept(c->description.atomic);
			break;
		case EXISTENTIAL_RESTRICTION:
			print_exists(c->description.exists);
			break;
		case CONJUNCTION:
			print_conjunction(c->description.conj);
			break;
		default:
			fprintf(stderr,"unknown concept type, aborting\n");
			exit(-1);
	}
}

void print_role(Role* r) {
	switch (r->type) {
		case ATOMIC_ROLE:
			// printf("%d ", r->description.role_id);
			print_atomic_role(r->description.atomic);
			break;
		default:
			fprintf(stderr,"unknown role type, aborting\n");
			exit(-1);
	}
}
	
void print_atomic_concept(AtomicConcept* ac) {
	printf("%s ", ac->name);
}

void print_exists(Exists* ex) {
	printf("(Some ");
	print_role(ex->role);
	print_concept(ex->filler);
	printf(")");
}

void print_conjunction(Conjunction* conj) {
	int i;
	printf("(And\n  ");
	for (i=0; i < conj->count; ++i) {
		print_concept(conj->conjuncts[i]);
		printf("\n  ");
	}
	printf(")");
}

void print_atomic_role(AtomicRole* ar) {
	printf("%s ", ar->name);
}

void print_subclass_axiom(SubClassAxiom* sc_ax) {
	printf("(SubClassOf\n  ");
	print_concept(sc_ax->lhs);
	printf(",\n  ");
	print_concept(sc_ax->rhs);
	printf(")\n");
}

void print_eqclass_axiom(EqClassAxiom* ec_ax) {
	printf("(EquivalentClasses\n  ");
	print_concept(ec_ax->lhs);
	printf(",\n  ");
	print_concept(ec_ax->rhs);
	printf(")\n");
}

// TODO
void print_subrole_axiom(SubRoleAxiom* subrole_ax) {
	printf("(SubObjectPropertyOf ");
	print_role(subrole_ax->lhs);
	printf(", ");
	print_role(subrole_ax->rhs);
	// printf("%d",subrole_ax->rhs);
	printf(")\n");
}

void print_axiom(Axiom* ax) {
	switch (ax->type) {
		case SUBCLASS_AX:
			print_subclass_axiom(ax->body.subclass_ax);
			break;
		case EQCLASS_AX:
			print_eqclass_axiom(ax->body.eqclass_ax);
			break;
		case SUBROLE_AX:
			print_subrole_axiom(ax->body.subrole_ax);
			break;
		default:
			fprintf(stderr, "unknown axiom type, aborting\n");
			exit(-1);
	}
}

void print_axioms(Axiom** axioms,int count) {
	int i;
	for (i = 0; i < count; ++i)
		print_axiom(axioms[i]);
}


void print_short_stats() {
	printf("---------- KB statistics ----------\n");
	printf("concepts: %d\nroles: %d\nsubclass ax: %d\neqclass ax: %d\nsubrole ax: %d\naxioms: %d\n",atomic_concept_count, atomic_role_count, subclass_ax_count, eqclass_ax_count, subrole_ax_count, tbox.axiom_count);
}

